package com.lsh.oms.core.service.order;

import com.lsh.oms.core.dao.order.OrderHeadDao;
import com.lsh.oms.core.dao.order.OrderHeadExtDao;
import com.lsh.oms.core.dao.order.OrderOperateLogDao;
import com.lsh.oms.core.enums.*;
import com.lsh.oms.core.model.order.OrderHead;
import com.lsh.oms.core.model.order.OrderHeadExt;
import com.lsh.oms.core.model.order.OrderOperateLog;
import com.lsh.oms.core.model.payment.OrderModel;
import com.lsh.oms.core.model.po.OmsTask;
import com.lsh.oms.core.service.asynservice.OmsEventBus;
import com.lsh.oms.core.service.po.OmsTaskService;
import com.lsh.oms.core.utils.OMSUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * 订单更新service
 *
 * @author panxudong
 * @date 16/9/1
 */
@Service
@Slf4j
public class OrderUpdateService {

    @Autowired
    private OrderHeadDao orderHeadDao;

    @Autowired
    private OrderHeadExtDao orderHeadExtDao;

    @Autowired
    private OrderOperateLogDao orderOperateLogDao;

    @Autowired
    private OmsTaskService omsTaskService;

    /**
     * 更新订单头信息
     *
     * @param entity
     * @param filter
     * @return
     */
    @Transactional(rollbackFor = RuntimeException.class)
    public int updateOrderHead(OrderHead entity, OrderHead filter) {

        return this.orderHeadDao.updateByFilter(entity, filter);
    }

    @Transactional(rollbackFor = RuntimeException.class)
    public boolean updateOrderStatus(Long orderCode, OrderStatus orderStatus, Integer lackDeliveryType) {
        log.info(orderCode + ":更新数据库参数:" + orderStatus.getIndex());

        int timestamp = OMSUtils.currentTime();
        OrderHead entity = new OrderHead();
        entity.setOrderStatus(orderStatus.getIndex());
        entity.setUpdateTime(timestamp);
        entity.setLackDeliveryType(lackDeliveryType);

        OrderHead filter = new OrderHead();
        filter.setOrderCode(orderCode);

        int num = this.updateOrderHead(entity, filter);
//        int num = orderUpdateService.updateOrderHead(dto.getOrderNo(), OrderStatus.indexOf(dto.getStatus()));
        log.info(orderCode + ":更新数据库结果:" + num);
        return num >= 1;
    }

    /**
     * 更新订单头信息
     *
     * @param orderCode
     * @param entity
     * @return
     */
    @Transactional(rollbackFor = RuntimeException.class)
    public int updateOrderHead(Long orderCode, OrderHead entity) {
        OrderHead filter = new OrderHead();
        filter.setOrderCode(orderCode);
        entity.setOrderCode(null);
        return this.updateOrderHead(entity, filter);
    }

    @Transactional(rollbackFor = RuntimeException.class)
    public int updateOrderHead(Long orderCode, OrderHead entity, Boolean addSplitTaskFlag, Long venderId) {
        OrderHead filter = new OrderHead();
        filter.setOrderCode(orderCode);
        entity.setOrderCode(null);

        int updateFlag = this.updateOrderHead(entity, filter);
        if (updateFlag > 0 && addSplitTaskFlag) {
            this.addTask(orderCode + "", venderId);
        }

        if (entity.getPayStatus() != null && entity.getPayStatus().equals(PayStatus.PAID.getValue())) {
            log.info("异步调用通知商城，支付成功");
            OmsEventBus.post(new OrderModel(orderCode, orderCode + ""));
        }

        return updateFlag;
    }


    @Transactional(rollbackFor = RuntimeException.class)
    public int updateOrderValid(Long orderCode) {
        OrderHead update = new OrderHead();
        update.setValid(0);
        update.setOrderStatus(OrderStatus.ORDER_CANCEL_CUSTOMERSERVICE.getIndex());
        OrderHead filter = new OrderHead();
        filter.setOrderCode(orderCode);

        return orderHeadDao.updateByFilter(update, filter);
    }

    /**
     * 更新订单状态
     *
     * @param orderCode
     * @param entity
     * @param orderOperateType (订单审核、订单提交OFC、订单提交DC、订单分拣、订单发货、订单完成、用户取消订单、客服取消订单)
     * @return
     */
    @Transactional(rollbackFor = RuntimeException.class)
    public int updateOrderStatus(Long orderCode, OrderHead entity, OrderOperateType orderOperateType, Long venderId) {
        Set<Integer> orderStatusExpect;
        OrderStatus orderStatusUpdate;
        switch (orderOperateType) {
            //订单审核
            case ORDER_AUDIT:
                //前置状态为`未编辑`
                orderStatusExpect = Collections.singleton(OrderStatus.ORDER_NO_EDIT.getIndex());
//                orderStatusUpdate = OrderStatus.ORDER_COMMITING_OFC; //状态修改为`可提交DC`
                //状态修改为`可提交DC`
                orderStatusUpdate = OrderStatus.ORDER_SPLIT_CHECK;
                break;
            //订单提交OFC
            case ORDER_COMMITTED_TO_OFC:
                //前置状态为`可提交DC`
                orderStatusExpect = Collections.singleton(OrderStatus.ORDER_COMMITING_OFC.getIndex());
                //状态修改为`已提交OFC`
                orderStatusUpdate = OrderStatus.ORDER_COMMITED_OFC;
                break;
            //订单提交DC
            case ORDER_COMMITTED_TO_WMS:
                //前置状态为`已提交OFC`
                orderStatusExpect = Collections.singleton(OrderStatus.ORDER_COMMITED_OFC.getIndex());
                //状态修改为`已提交DC`
                orderStatusUpdate = OrderStatus.ORDER_WM_NEW;
                break;
            case ORDER_SORTING:
                orderStatusExpect = Collections.singleton(OrderStatus.ORDER_WM_NEW.getIndex());
                orderStatusUpdate = OrderStatus.ORDER_SORTING;
                break;
            case ORDER_DELIVERY:
                orderStatusExpect = Collections.singleton(OrderStatus.ORDER_SORTING.getIndex());
                orderStatusUpdate = OrderStatus.ORDER_DELIVERY;
                break;
            case ORDER_ARRIVED:
                orderStatusExpect = new HashSet<>(4);
                orderStatusExpect.add(OrderStatus.ORDER_SORTING.getIndex());
                orderStatusExpect.add(OrderStatus.ORDER_DELIVERY.getIndex());
                orderStatusUpdate = OrderStatus.ORDER_SIGN;
                break;
            case ORDER_FINISH:
                orderStatusExpect = Collections.singleton(OrderStatus.ORDER_SIGN.getIndex());
                orderStatusUpdate = OrderStatus.ORDER_FINISH;
                break;
            case ORDER_CANCEL_BY_CUSTOMER:
                orderStatusExpect = new HashSet<>(4);
                orderStatusExpect.add(OrderStatus.ORDER_NEW.getIndex());
                orderStatusExpect.add(OrderStatus.ORDER_NO_EDIT.getIndex());
                orderStatusExpect.add(OrderStatus.ORDER_COMMITING_OFC.getIndex());
                orderStatusUpdate = OrderStatus.ORDER_CANCEL_CUSTOMER;
                break;
            case ORDER_CANCEL_BY_CUSTOM_SERVICE:
                orderStatusExpect = new HashSet<>(4);
                orderStatusExpect.add(OrderStatus.ORDER_PRE.getIndex());
                orderStatusExpect.add(OrderStatus.ORDER_NEW.getIndex());
                orderStatusExpect.add(OrderStatus.ORDER_NO_EDIT.getIndex());
                orderStatusExpect.add(OrderStatus.ORDER_COMMITING_OFC.getIndex());
                orderStatusExpect.add(OrderStatus.ORDER_WM_NEW.getIndex());
                orderStatusUpdate = OrderStatus.ORDER_CANCEL_CUSTOMERSERVICE;
                break;
            case ORDER_STATUS_ROLLBACK_2_DELIVERED:
                orderStatusExpect = new HashSet<>(4);
                orderStatusExpect.add(OrderStatus.ORDER_SIGN.getIndex());
                orderStatusExpect.add(OrderStatus.ORDER_FINISH.getIndex());
                orderStatusUpdate = OrderStatus.ORDER_DELIVERY;
                break;
            default:
                throw new RuntimeException("不允许`" + orderOperateType.getDesc() + "`操作！");
        }
        OrderHead filter = new OrderHead();
        filter.setOrderCode(orderCode);
        OrderHead head = this.orderHeadDao.findOne(filter);
        Integer orderStatus = head.getOrderStatus();
        if (orderStatus.intValue() == orderStatusUpdate.getIndex()) {
            return 0;
        }
        if (!CollectionUtils.isEmpty(orderStatusExpect) && !orderStatusExpect.contains(orderStatus)) {
            return -1;
        }
        Integer timestamp = OMSUtils.currentTime();
        filter.setOrderStatus(orderStatus);
        if (entity == null) {
            entity = new OrderHead();
        }
        entity.setOrderStatus(orderStatusUpdate.getIndex());
        entity.setUpdateTime(timestamp);
        int ret = this.updateOrderHead(entity, filter);
        if (ret > 1) {
            throw new RuntimeException("更新订单状态影响多条记录！订单号=" + orderCode);
        }

        if (ret == 1 && orderStatusUpdate.getIndex() == OrderStatus.ORDER_SPLIT_CHECK.getIndex()) {
            log.info("orderCode {} addTask start ", orderCode);
            this.addTask(orderCode + "", venderId);
        } else {
            log.info("orderCode {} not addTask start ", orderCode);
        }

        OrderOperateLog operateLog = new OrderOperateLog();
        operateLog.setOrderCode(orderCode);
        operateLog.setOrderType(OperateOrderType.ORDER.getValue());
        operateLog.setOperateType(orderOperateType.getValue());
        operateLog.setOperateDesc(new StringBuilder(orderOperateType.getDesc()).append("，订单状态从`").append(OrderStatus.getName(orderStatus)).append("`更新为`").append(orderStatusUpdate.getName()).append("`").toString());
        operateLog.setOperateTime(timestamp);
        operateLog.setCreateTime(timestamp);
        operateLog.setVenderId(head.getVenderId());
        this.orderOperateLogDao.insert(operateLog);

        return ret;

    }

    public void addTask(String orderCode, Long venderId) {

        OmsTask filter = new OmsTask();
        filter.setRefCode(orderCode);
        filter.setTaskType(TaskType.ORDER_SPLIT.getCode());
        List<OmsTask> omsTasks = omsTaskService.getTasksByFilter(filter);

        if (!CollectionUtils.isEmpty(omsTasks)) {
            log.info("orderCode {} select omsTasks size ", orderCode, omsTasks.size());
            return;
        }
        log.info("orderCode {} select omsTasks size 0", orderCode);

        Integer timestamp = (int) (System.currentTimeMillis() / 1000);

        OmsTask omsTask = new OmsTask();
        omsTask.setRefCode(orderCode);
        omsTask.setContent(orderCode);
        omsTask.setTaskType(TaskType.ORDER_SPLIT.getCode());
        omsTask.setTaskStatus(TaskStatus.TASK_UN_DEAL.getCode());
        omsTask.setExecCount(0);
        omsTask.setCreateTime(timestamp);
        omsTask.setUpdateTime(timestamp);
        omsTask.setVenderId(venderId);

        this.omsTaskService.add(omsTask);
    }

    /**
     * 更新订单状态
     *
     * @param orderCode
     * @param orderStatus
     * @return
     */
    @Transactional(rollbackFor = RuntimeException.class)
    public int updateOrderStatus(Long orderCode, OrderStatus orderStatus) {
        int timestamp = OMSUtils.currentTime();
        OrderHead entity = new OrderHead();
        entity.setOrderStatus(orderStatus.getIndex());
        entity.setUpdateTime(timestamp);

        int ret = this.updateOrderHead(orderCode, entity);
        if (ret > 1) {
            throw new RuntimeException("更新订单状态影响多条记录！订单号=" + orderCode);
        }

        return ret;
    }

    @Transactional(rollbackFor = RuntimeException.class)
    public int updateOrderStatus2(OrderHead entity) {

        entity.setUpdateTime(OMSUtils.currentTime());

        int ret = this.updateOrderHead(entity.getOrderCode(), entity);
        if (ret > 1) {
            throw new RuntimeException("更新订单状态影响多条记录！订单号=" + entity.getOrderCode());
        }

        return ret;
    }


    @Transactional(rollbackFor = RuntimeException.class)
    public int updateOrderExt(OrderHeadExt orderHeadExt) {

        return orderHeadExtDao.update(orderHeadExt);
    }
}
